/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package simplepushserver.filesend;

import java.io.*;
import java.util.*;
import java.util.ArrayList;
import java.util.zip.*;
import simplepushserver.file.FileUtils;

/**
 *
 * @author Fille
 */
public class Zipper {
    static final int BUFFER = 8192;
    static final int METHOD = ZipEntry.STORED;


    /**
     * @param list List with the files including folders, first must be the structurefolder
     */
    public static boolean enZip(List<File> list, OutputStream output){
        try {
            BufferedInputStream fileReader = null;
            ZipOutputStream out = new ZipOutputStream(output);
            out.setLevel(ZipOutputStream.STORED);
            
            File orgDir = list.get(0);
            list.remove(0);
            for (int i=0; i<list.size(); i++) {    
                while (list.get(i).isDirectory()) {                    
                    list.remove(i);
                }
                fileReader = new BufferedInputStream(new FileInputStream(list.get(i)) , BUFFER);
                String currentFileNamePath = FileUtils.getDirOffset(orgDir, list.get(i));
                ZipEntry entry = new ZipEntry(currentFileNamePath);
                out.putNextEntry(entry);
                ByteBlockSender bbzs = new ByteBlockSender(fileReader, out, BUFFER);
                bbzs.run();
                out.closeEntry();
                fileReader.close();   
            }
            System.err.println(list.size()+" files was Zipped!");
            out.finish();
            out.close();
            return true;
       }catch(Exception e) {
            e.printStackTrace();
            return false;
       }
    }
    public static boolean enZip(List<File> list, File newFile){
        try {
            return enZip(list, new BufferedOutputStream(new FileOutputStream(newFile)));
        } catch (FileNotFoundException ex) {
            System.err.println(ex);
            return false;
        }
    }
    public static boolean enZip(File selectedFile, File newFile) {
        if(selectedFile.isDirectory()) {
            return enZip(FileUtils.listFiles(selectedFile, false), newFile);
        }else{
            ArrayList<File> list = new ArrayList<File>();
            list.add(selectedFile);
            return enZip(list, newFile);
        }
    }
    public static boolean unZip(File zipFile, File destinationFolder){
        try {
            if(!destinationFolder.exists()) {
                destinationFolder.mkdir();
            }
            ZipFile zf = new ZipFile(zipFile);
            Enumeration< ? extends ZipEntry> zipEnum = zf.entries();
            String dir = destinationFolder.getAbsolutePath();
            byte data[] = new byte[BUFFER];
            while( zipEnum.hasMoreElements() ) {
                ZipEntry item = (ZipEntry) zipEnum.nextElement();
                System.out.print("Extracting: "+item.getName());
                if (item.isDirectory()){
                    File newdir = new File(dir + File.separator + item.getName());
                    newdir.mkdir();
                }else{
                    String newfilePath = dir + File.separator + item.getName();
                    File newFile = new File(newfilePath);
                    if (!newFile.getParentFile().exists()) {
                        newFile.getParentFile().mkdirs();
                    }
                    InputStream is = zf.getInputStream(item);
                    FileOutputStream fos = new FileOutputStream(newfilePath);
                    int count;
                    while( (count = is.read(data)) != -1 ) {
                        fos.write(data, 0, count);
                    }
                    is.close();
                    fos.close();
               }
               System.out.print(" done! \n");
           }
           zf.close();
           return true;
        }catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    public static ArrayList<File> toList(File[] fArr){
        ArrayList<File> list = new ArrayList<File>();
        for(File f : fArr){
            if(f.isDirectory()) {
                list.addAll(FileUtils.listFiles(f, false));
            }else{
                list.add(f);
            }
        }
        return list;
    }
}
